package com.analysis.client;

import com.analysis.config.CommonConstant;
import com.analysis.config.TencentChatConfig;
import com.analysis.dto.AiCallResponse;
import com.analysis.dto.Reference;
import com.analysis.dto.TencentChatRequest;
import com.analysis.utils.LogUtils;
import com.analysis.utils.ParseTextUtils;
import com.analysis.utils.StreamResponseProcessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;

/**
 * 腾讯云智能体开发平台对话端接口客户端
 * 基于腾讯云文档：https://cloud.tencent.com/document/product/1759/105561
 * <p>
 * 支持HTTP SSE（Server-Sent Events）流式对话
 */
@Component
public class TencentAgentAIChatClient {

    private static final Logger logger = LoggerFactory.getLogger(TencentAgentAIChatClient.class);

    @Autowired
    private TencentChatConfig tencentChatConfig;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ObjectMapper objectMapper;


    /**
     * 发送流式对话请求并获取最终答案
     *
     * @param content 消息内容
     * @return 最终答案内容
     */
    public AiCallResponse callQuesion(String content) {
        AiCallResponse aiCallResponse = sendStreamMessage(content + CommonConstant.QUESTION_SIZE, null, null, null, null, null, null, null, null);
        if (aiCallResponse.getText() != null) {
            aiCallResponse.setContents(ParseTextUtils.parseCommonText(aiCallResponse.getText()));
        }
        return aiCallResponse;
    }

    /**
     * 发送流式对话请求并获取最终答案（带完整参数）
     *
     * @param content               消息内容
     * @param sessionId             会话ID
     * @param visitorBizId          访客ID
     * @param streamingThrottle     流式回复频率控制
     * @param enableThought         是否启用思考过程展示
     * @param enableReference       是否启用参考来源展示
     * @param enableTokenStatistics 是否启用token统计
     * @param searchNetwork         联网搜索控制
     * @param stream                流式传输控制
     * @return 最终答案内容
     */
    public AiCallResponse sendStreamMessage(String content, String sessionId, String visitorBizId,
                                            Integer streamingThrottle, Boolean enableThought,
                                            Boolean enableReference, Boolean enableTokenStatistics,
                                            String searchNetwork, String stream) {

        TencentChatRequest request = buildRequest(content, sessionId, visitorBizId,
                streamingThrottle, enableThought, enableReference, enableTokenStatistics, searchNetwork, stream);

        try {
            // 创建流式响应处理器（每次调用都创建新实例，确保内存安全）
            StreamResponseProcessor processor = new StreamResponseProcessor(objectMapper);

            try {
                // 使用HttpURLConnection处理SSE流
                processSseStreamWithProcessor(request, processor);

                if (processor.getTokenCount() > 0) {
                    System.err.println("元宝消耗token数：" + processor.getTokenCount());
                }


                // 获取最终答案
                String finalAnswer = processor.getFinalAnswer();
                AiCallResponse aiCallResponse = new AiCallResponse();
                aiCallResponse.setText(finalAnswer);

                // 设置参考来源信息
                List<Reference> references = processor.getReferences();
                aiCallResponse.setReferences(references);
                return aiCallResponse;
            } finally {
                // 确保处理器资源被清理（虽然每次都是新实例，但显式清理更安全）
                processor.reset();
            }
        } catch (Exception e) {
            LogUtils.logError(logger, "发送腾讯云智能体流式对话请求并获取最终答案异常", e);
            return new AiCallResponse();
        }
    }

    /**
     * 构建请求对象
     */
    private TencentChatRequest buildRequest(String content, String sessionId, String visitorBizId,
                                            Integer streamingThrottle, Boolean enableThought,
                                            Boolean enableReference, Boolean enableTokenStatistics,
                                            String searchNetwork, String stream) {
        String requestId = UUID.randomUUID().toString();
        TencentChatRequest request = new TencentChatRequest();
        request.setRequestId(requestId);
        request.setSessionId(sessionId != null ? sessionId : requestId);
        request.setVisitorBizId(visitorBizId != null ? visitorBizId : requestId);
        request.setContent(content);
        request.setBotAppKey(tencentChatConfig.getBotAppKey());
        request.setStreamingThrottle(streamingThrottle != null ? streamingThrottle : tencentChatConfig.getDefaultStreamingThrottle());
        request.setEnableThought(enableThought != null ? enableThought : tencentChatConfig.getDefaultEnableThought());
        request.setEnableReference(enableReference != null ? enableReference : tencentChatConfig.getDefaultEnableReference());
        request.setEnableTokenStatistics(enableTokenStatistics != null ? enableTokenStatistics : tencentChatConfig.getDefaultEnableTokenStatistics());
        request.setSearchNetwork(searchNetwork != null ? searchNetwork : tencentChatConfig.getDefaultSearchNetwork());
        request.setStream(stream != null ? stream : tencentChatConfig.getDefaultStream());

        return request;
    }

    /**
     * 处理SSE流（使用流式响应处理器）
     */
    private void processSseStreamWithProcessor(TencentChatRequest request,
                                               StreamResponseProcessor processor) throws IOException {

        URL url = new URL(tencentChatConfig.getApiUrl());
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        try {
            // 设置请求方法和头部
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            connection.setRequestProperty("Accept", "text/event-stream; charset=UTF-8");
            connection.setRequestProperty("Cache-Control", "no-cache");
            connection.setRequestProperty("Accept-Charset", "UTF-8");
            connection.setConnectTimeout(tencentChatConfig.getConnectTimeout());
            connection.setReadTimeout(tencentChatConfig.getReadTimeout());
            connection.setDoOutput(true);

            // 发送请求体
            String requestJson = objectMapper.writeValueAsString(request);
            byte[] requestBytes = requestJson.getBytes(StandardCharsets.UTF_8);
            connection.getOutputStream().write(requestBytes);

            // 读取响应
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpStatus.OK.value()) {
                try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {

                    String line;
                    StringBuilder eventData = new StringBuilder();
                    String eventType = null;

                    long startTime = System.currentTimeMillis();
                    long timeout = 60000; // 60秒超时

                    while ((line = reader.readLine()) != null) {
                        // 检查超时
                        if (System.currentTimeMillis() - startTime > timeout) {
                            logger.warn("流式响应处理超时，已处理事件数: {}", processor.getAllResponses().size());
                            break;
                        }
                        if (line.startsWith("event:")) {
                            eventType = line.substring(6).trim();
                        } else if (line.startsWith("data:")) {
                            String data = line.substring(5).trim();
                            if (!data.isEmpty()) {
                                eventData.append(data);

                                // 检查是否是完整的事件数据
                                if (data.endsWith("}")) {
                                    // 使用处理器处理事件
                                    processor.processEvent(eventType, eventData.toString(), null, null);

                                    // 如果已完成，可以提前退出
                                    if (processor.isComplete()) {
                                        break;
                                    }

                                    // 重置事件数据
                                    eventData.setLength(0);
                                    eventType = null;
                                }
                            }
                        }
                    }
                }
            } else {
                String errorMessage = "HTTP请求失败，状态码：" + responseCode;
                LogUtils.logError(logger, errorMessage);
                throw new RuntimeException(errorMessage);
            }

        } finally {
            connection.disconnect();
        }
    }


}
